package com.codedancer.campus.manager.service.impl;

import cn.afterturn.easypoi.entity.vo.NormalExcelConstants;
import cn.afterturn.easypoi.excel.entity.ExportParams;
import cn.afterturn.easypoi.excel.entity.enmus.ExcelType;
import cn.afterturn.easypoi.view.PoiBaseView;
import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.date.DateUtil;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.codedancer.campus.common.exception.BusinessException;
import com.codedancer.campus.manager.service.IConfessionalWallService;
import com.codedancer.campus.manager.service.bo.confessionalWall.ConfessionalWallPageSearchBo;
import com.codedancer.campus.manager.service.excel.ConfessionalWallExcel;
import com.codedancer.campus.manager.service.vo.confessionalWall.ConfessionalWallPageVo;
import com.codedancer.campus.manager.service.vo.confessionalWall.ConfessionalWallVo;
import com.codedancer.campus.mapper.ConfessionalWallImageMapper;
import com.codedancer.campus.mapper.ConfessionalWallMapper;
import com.codedancer.campus.mapper.SchoolMapper;
import com.codedancer.campus.mapper.UserMapper;
import com.codedancer.campus.po.ConfessionalWall;
import com.codedancer.campus.po.ConfessionalWallImage;
import com.codedancer.campus.po.School;
import com.codedancer.campus.po.User;
import com.codedancer.campus.qo.confessionalWall.ConfessionalWallSearchQo;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import lombok.extern.slf4j.Slf4j;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

@Service
@Transactional(rollbackFor = Exception.class)
@Slf4j
public class ConfessionalWallServiceImpl implements IConfessionalWallService {

    @Autowired
    private ConfessionalWallMapper confessionalWallMapper;
    @Autowired
    private ConfessionalWallImageMapper confessionalWallImageMapper;
    @Autowired
    private UserMapper userMapper;
    @Autowired
    private SchoolMapper schoolMapper;

    /**
     * 分页查询表白墙
     *
     * @param confessionalWallPageSearchBo
     * @return
     */
    @Override
    public IPage<ConfessionalWallPageVo> page(
        ConfessionalWallPageSearchBo confessionalWallPageSearchBo) {
        ConfessionalWallSearchQo confessionalWallSearchQo = BeanUtil
            .copyProperties(confessionalWallPageSearchBo, ConfessionalWallSearchQo.class);
        IPage<ConfessionalWall> confessionalWallIPage = confessionalWallMapper.pageToManager(
            new Page<>(confessionalWallPageSearchBo.getPage(),
                confessionalWallPageSearchBo.getSize()), confessionalWallSearchQo);
        IPage<ConfessionalWallPageVo> confessionalWallPageVoIPage = new Page<>();
        List<ConfessionalWallPageVo> confessionalWallPageVos;
        confessionalWallPageVos = confessionalWallIPage.getRecords().stream()
            .map(confessionalWall -> {
                ConfessionalWallPageVo confessionalWallPageVo = BeanUtil
                    .copyProperties(confessionalWall, ConfessionalWallPageVo.class);
                confessionalWallPageVo
                    .setPublishNickName(confessionalWall.getPublishUser().getNickName());
                confessionalWallPageVo
                    .setPublishSchoolName(confessionalWall.getPublishSchool().getName());
                // 查询发布的图片信息
                List<ConfessionalWallImage> confessionalWallImages = confessionalWallImageMapper
                    .selectListByColumn("confessional_wall_uuid", confessionalWall.getUuid());
                confessionalWallPageVo.setImages(
                    confessionalWallImages.stream().map(ConfessionalWallImage::getImageUrl).collect(
                        Collectors.toList()));
                return confessionalWallPageVo;
            }).collect(Collectors.toList());
        confessionalWallPageVoIPage.setTotal(confessionalWallIPage.getTotal());
        confessionalWallPageVoIPage.setRecords(confessionalWallPageVos);
        return confessionalWallPageVoIPage;
    }

    /**
     * 删除表白墙
     *
     * @param uuid
     */
    @Override
    public void delete(String uuid) {
        if (!confessionalWallMapper.existsByUuId(uuid)) {
            throw new BusinessException("表白墙不存在");
        }
        confessionalWallMapper.deleteById(uuid);
    }

    /**
     * 导出表白墙
     *
     * @param request
     * @param response
     * @param confessionalWallPageSearchBo
     */
    @Override
    public void export(HttpServletRequest request, HttpServletResponse response,
        ConfessionalWallPageSearchBo confessionalWallPageSearchBo) {
        log.info("开始导出表白墙数据");
        ConfessionalWallSearchQo confessionalWallSearchQo = BeanUtil
            .copyProperties(confessionalWallPageSearchBo, ConfessionalWallSearchQo.class);
        // 先查询出需要导出的表白墙数据
        List<ConfessionalWall> confessionalWalls = confessionalWallMapper
            .listExportConfessionalWall(confessionalWallSearchQo);
        // 组装数据
        List<ConfessionalWallExcel> confessionalWallExcels = assembleData(confessionalWalls);
        Map<String, Object> map = new HashMap<>();
        ExportParams params = new ExportParams("表白墙列表", "表白墙列表", ExcelType.HSSF);
        map.put(NormalExcelConstants.DATA_LIST, confessionalWallExcels);
        map.put(NormalExcelConstants.CLASS, ConfessionalWallExcel.class);
        map.put(NormalExcelConstants.PARAMS, params);
        map.put(NormalExcelConstants.FILE_NAME, "表白墙列表" + DateUtil.today());
        PoiBaseView.render(map, request, response, NormalExcelConstants.EASYPOI_EXCEL_VIEW);
        log.info("表白墙数据导出完成");
    }

    /**
     * 表白墙详情
     * @param uuid
     * @return
     */
    @Override
    public ConfessionalWallVo detail(String uuid) {
        ConfessionalWall confessionalWall = confessionalWallMapper.findById(uuid)
            .orElseThrow(() -> new BusinessException("表白墙不存在"));
        ConfessionalWallVo confessionalWallVo = BeanUtil
            .copyProperties(confessionalWall, ConfessionalWallVo.class);
        // 查询发布用户
        User user = userMapper.selectById(confessionalWall.getPublishUserUuid());
        confessionalWallVo.setPublishNickName(user.getNickName());
        confessionalWallVo.setAvatar(user.getAvatar());
        School school = schoolMapper.selectById(confessionalWall.getPublishSchoolUuid());
        confessionalWallVo.setPublishSchoolName(school.getName());
        // 查询发布的图片
        List<ConfessionalWallImage> confessionalWallImages = confessionalWallImageMapper
            .selectListByColumn("confessional_wall_uuid", confessionalWall.getUuid());
        confessionalWallVo.setImages(
            confessionalWallImages.stream().map(ConfessionalWallImage::getImageUrl).collect(
                Collectors.toList()));
        return confessionalWallVo;
    }

    /**
     * 组装数据 将confessionalWall转化为ConfessionalWallExcel
     *
     * @param confessionalWalls
     * @return
     */
    private List<ConfessionalWallExcel> assembleData(List<ConfessionalWall> confessionalWalls) {
        return confessionalWalls.stream().map(confessionalWall -> {
            ConfessionalWallExcel confessionalWallExcel = BeanUtil
                .copyProperties(confessionalWall, ConfessionalWallExcel.class);
            confessionalWallExcel
                .setPublishNickName(confessionalWall.getPublishUser().getNickName());
            confessionalWallExcel
                .setPublishSchoolName(confessionalWall.getPublishSchool().getName());
            return confessionalWallExcel;
        }).collect(Collectors.toList());
    }
}
